using System;
using Deepcode.Flux.Core.Extensions;
using Deepcode.Flux.Core.Extensions.Codons;
using Deepcode.Flux.Core.Systems.Asset;

namespace Deepcode.Flux.Core.Codons.Asset
{
	/// <summary>
	/// Codon representing an action that can be executed against
	/// a particular asset - file or folder.
	/// </summary>
	[XmlCodonName("AssetAction")]
	public class AssetAction : AbstractPermissionCodon
	{
		#region Codon XML Attributes
		[XmlCodonAttribute("text")]
		private string text = "";
		[XmlCodonAttribute("usemask")]
		private string usemask = "";
		[XmlCodonAttribute("useextensions")]
		private string useextensions = "";
		[XmlCodonAttribute("action")]
		private string action = "";
		[XmlCodonAttribute("preaction")]
		private string preaction = "";
		[XmlCodonAttribute("target")]
		private string target = "";
		#endregion
		#region Build Item
		public override object BuildItem(object owner, System.Collections.ArrayList subItems)
		{
			// Ensure we pass in an AssetActionContext object
			if (!(owner is AssetActionContext)) throw new Exception("AssetAction BuildItem must be passed an AssetActionContext object");
			
			// Check the user's permissions
			if (!CheckUser()) return null;

			// Get the context passed in
			AssetActionContext Owner = (AssetActionContext) owner;

			// Check the use mask allows this action to be executed on this context
			int UseMask = GetMask();
			if((UseMask & ((int) Owner.State)) == 0 ) return null;

			// If it's file based, check the extension matches
			if( ! ExtensionCheck( Owner.Extension )) return null;

			// Build up the strings to make the action
			string ActionString = action;
			ActionString = ActionString.Replace("{PATH}", Owner.Path);
			ActionString = ActionString.Replace("{FILE}", Owner.Path +"/"+ Owner.Filename);
			ActionString = ActionString.Replace("{FILEURL}", Owner.Page.ResolveUrl( Owner.Path + "/" + Owner.Filename ));

			// It's okay to use this action - build it
			AssetActionButton b = new AssetActionButton( 
				text, 
				ActionString,
				preaction, 
				target );

			return b;
		}
		#endregion
		#region Utility
		/// <summary>
		/// Checks that the extension ex is in the list
		/// of usable extensions as defined in the addin file
		/// </summary>
		/// <param name="ex"></param>
		/// <returns></returns>
		private bool ExtensionCheck(string ex)
		{
			if( useextensions == "" ) return true;
			string [] exts = useextensions.Split(';');
			foreach( string e in exts )
				if( e.ToUpper() == ex ) return true;

			return false;
		}
		/// <summary>
		/// Gets the mask of states that this action can be
		/// used against. IE: ROOT, FILE, FOLDER etc...
		/// </summary>
		/// <returns></returns>
		private int GetMask()
		{
			int result = 0;
			string [] maskitems = usemask.Split('|');
			
			// If no mask has been specified, allow all
			if ((usemask == "") || (maskitems.Length<1))
				return  ((int) (AssetActionUse.ROOT | AssetActionUse.FILE | AssetActionUse.FOLDER));
			
			// Translate each mask option into it's mask key
			foreach (string i in maskitems)
			{
				string i2 = i.ToUpper();
				if( i2 == "ROOT" ) result = result | ((int) AssetActionUse.ROOT);
				if( i2 == "FILE" ) result = result | ((int) AssetActionUse.FILE);
				if( i2 == "FOLDER" ) result = result | ((int) AssetActionUse.FOLDER);
			}
			
			return result;
		}
		#endregion
	}

}
